package com.celer;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.celer.generator.CompanyGenerator;
import com.celer.generator.PersonGenerator;
import lombok.extern.slf4j.Slf4j;
import com.celer.randomobj.Company;
import com.celer.randomobj.Person;
import com.celer.util.JsonUtils;

import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.*;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class SwingMain {
    public static void main(String[] args) {
        // 创建窗口
        JFrame frame = new JFrame("测试数据生成器");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 获取屏幕尺寸
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int width = (int) (screenSize.width * 0.5);
        int height = (int) (screenSize.height * 0.5);
        frame.setSize(width, height);

        // 设置窗口居中
        frame.setLocationRelativeTo(null);

        // 设置主面板的布局为 GridBagLayout
        frame.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        // 设置组件之间的间距
        gbc.insets = new Insets(5, 5, 5, 5);

        // 创建文本框
        JTextPane textPane = new JTextPane();
        textPane.setEditable(false);
        // 设置字体和大小
        textPane.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20));
        JScrollPane scrollPane = new JScrollPane(textPane);

        // 创建按钮
        JButton personButton = new JButton("生成个人信息");
        // 设置按钮字体和大小
        personButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20));
        JButton companyButton = new JButton("生成公司信息");
        // 设置按钮字体和大小
        companyButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 20));

        // 设置按钮边框为null，消除边框
        personButton.setBorder(null);
        // 设置按钮边框为null，消除边框
        companyButton.setBorder(null);
        // 设置焦点不可见
        personButton.setFocusPainted(false);
        // 设置焦点不可见
        companyButton.setFocusPainted(false);

        // 添加按钮的点击事件
        personButton.addActionListener(e -> {
            Person person = Person.builder().build();
            PersonGenerator.generatePerson(person);
            String json = "";
            try {
                json = JsonUtils.toJsonStr(person);
            } catch (Exception ex) {
                log.error("生成个人信息时出错:{}", ex.getMessage());
            }
            displayFormattedJson(textPane, json);
        });

        companyButton.addActionListener(e -> {
            Company company = new Company();
            CompanyGenerator.generateCompany(company);
            String json = "";
            try {
                json = JsonUtils.toJsonStr(company);
            } catch (Exception ex) {
                log.error("生成公司信息时出错:{}", ex.getMessage());
            }
            displayFormattedJson(textPane, json);
        });

        // 添加第一个按钮
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 0.1;
        gbc.weighty = 0.1;
        frame.add(personButton, gbc);

        // 添加第二个按钮
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 0.1;
        gbc.weighty = 0.1;
        frame.add(companyButton, gbc);

        // 添加文本框
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.gridheight = 2;
        gbc.weightx = 0.9;
        gbc.weighty = 1.0;
        frame.add(scrollPane, gbc);

        // 显示窗口
        frame.setVisible(true);
    }

    private static void displayFormattedJson(JTextPane textPane, String json) {
        // 清除现有内容
        textPane.setText("");

        // 创建 ObjectMapper 实例
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        // 获取文本样式
        StyledDocument doc = textPane.getStyledDocument();
        Style keyStyle = doc.addStyle("KeyStyle", null);
        StyleConstants.setForeground(keyStyle, Color.BLUE);

        Style valueStyle = doc.addStyle("ValueStyle", null);
        StyleConstants.setForeground(valueStyle, Color.BLACK);

        try {
            // 将 JSON 字符串解析为 JsonNode
            JsonNode rootNode = mapper.readTree(json);
            // 计算键的最大长度
            int maxKeyLength = calculateMaxKeyLength(rootNode);
            // 递归处理 JSON 节点
            processJsonNode(rootNode, doc, keyStyle, valueStyle, 0,maxKeyLength);
        } catch (IOException | BadLocationException e) {
            log.error("格式化JSON时出错:{}", e.getMessage());
        }
    }


    private static int calculateMaxKeyLength(JsonNode node) {
        int maxKeyLength = 0;
        if (node.isObject()) {
            Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> field = fields.next();
                maxKeyLength = Math.max(maxKeyLength, field.getKey().length());
                maxKeyLength = Math.max(maxKeyLength, calculateMaxKeyLength(field.getValue()));
            }
        }
        return maxKeyLength;
    }

    private static void processJsonNode(JsonNode node, StyledDocument doc, Style keyStyle, Style valueStyle, int indentLevel, int maxKeyLength) throws BadLocationException {
        if (node.isObject()) {
            Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> field = fields.next();
                // 添加缩进
                addIndentation(doc, indentLevel);
                // 插入 key
                doc.insertString(doc.getLength(), field.getKey(), keyStyle);
                // 计算需要补齐的空格数量
                int spacesToAdd = maxKeyLength - field.getKey().length();
                for (int i = 0; i < spacesToAdd; i++) {
                    doc.insertString(doc.getLength(), " ", null);
                }
                doc.insertString(doc.getLength(), ": ", null);
                // 递归处理子节点
                processJsonNode(field.getValue(), doc, keyStyle, valueStyle, indentLevel + 1, maxKeyLength);
                doc.insertString(doc.getLength(), "\n", null);
            }
        } else if (node.isArray()) {
            for (JsonNode arrayItem : node) {
                // 添加缩进
                addIndentation(doc, indentLevel);
                // 递归处理数组中的每个元素
                processJsonNode(arrayItem, doc, keyStyle, valueStyle, indentLevel + 1, maxKeyLength);
                doc.insertString(doc.getLength(), "\n", null);
            }
        } else {
            // 插入 value，去除引号
            String value = node.toString().replace("\"", "");
            doc.insertString(doc.getLength(), value, valueStyle);
        }
    }

    private static void addIndentation(StyledDocument doc, int indentLevel) throws BadLocationException {
        for (int i = 0; i < indentLevel; i++) {
            doc.insertString(doc.getLength(), "    ", null); // 每级缩进4个空格
        }
    }

}
